package craky.componentc;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicScrollBarUI;

import craky.util.UIResourceManager;

public class CScrollBarUI extends BasicScrollBarUI implements MouseListener
{
    private static final int DEFAULT_SCROLLBAR_WIDTH = 14;

    private static final Color BORDER_COLOR = UIResourceManager.getColor(UIResourceManager.KEY_SCROLL_BAR_BORDER_COLOR);
    
    private static final Color BACKGROUND = UIResourceManager.getColor(UIResourceManager.KEY_SCROLL_BAR_BACKGROUND);

    protected JCButton increaseButton;

    protected JCButton decreaseButton;
    
    private boolean pressed;
    
    public static ComponentUI createUI(JComponent c)
    {
        return new CScrollBarUI();
    }

    protected JButton createIncreaseButton(int orientation)
    {
        if(increaseButton == null)
        {
            increaseButton = new JCButton();
            increaseButton.setFocusable(false);
            increaseButton.setRequestFocusEnabled(false);
            
            if(scrollbar.getOrientation() == VERTICAL)
            {
                increaseButton.setImage(UIResourceManager.getImage(UIResourceManager.KEY_SCROLL_BAR_DOWN_IMAGE));
                increaseButton.setRolloverImage(UIResourceManager.getImage(UIResourceManager.KEY_SCROLL_BAR_DOWN_ROLLOVER_IMAGE));
                increaseButton.setPressedImage(UIResourceManager.getImage(UIResourceManager.KEY_SCROLL_BAR_DOWN_PRESSED_IMAGE));
            }
            else
            {
                increaseButton.setImage(UIResourceManager.getImage(UIResourceManager.KEY_SCROLL_BAR_RIGHT_IMAGE));
                increaseButton.setRolloverImage(UIResourceManager.getImage(UIResourceManager.KEY_SCROLL_BAR_RIGHT_ROLLOVER_IMAGE));
                increaseButton.setPressedImage(UIResourceManager.getImage(UIResourceManager.KEY_SCROLL_BAR_RIGHT_PRESSED_IMAGE));
            }
            
            Image image = increaseButton.getImage();
            increaseButton.setPreferredSize(new Dimension(image.getWidth(null), image.getHeight(null)));
        }

        return increaseButton;
    }
    
    protected JButton createDecreaseButton(int orientation)
    {
        if(decreaseButton == null)
        {
            decreaseButton = new JCButton();
            decreaseButton.setFocusable(false);
            decreaseButton.setRequestFocusEnabled(false);
            
            if(scrollbar.getOrientation() == VERTICAL)
            {
                decreaseButton.setImage(UIResourceManager.getImage(UIResourceManager.KEY_SCROLL_BAR_UP_IMAGE));
                decreaseButton.setRolloverImage(UIResourceManager.getImage(UIResourceManager.KEY_SCROLL_BAR_UP_ROLLOVER_IMAGE));
                decreaseButton.setPressedImage(UIResourceManager.getImage(UIResourceManager.KEY_SCROLL_BAR_UP_PRESSED_IMAGE));
            }
            else
            {
                decreaseButton.setImage(UIResourceManager.getImage(UIResourceManager.KEY_SCROLL_BAR_LEFT_IMAGE));
                decreaseButton.setRolloverImage(UIResourceManager.getImage(UIResourceManager.KEY_SCROLL_BAR_LEFT_ROLLOVER_IMAGE));
                decreaseButton.setPressedImage(UIResourceManager.getImage(UIResourceManager.KEY_SCROLL_BAR_LEFT_PRESSED_IMAGE));
            }
            
            Image image = decreaseButton.getImage();
            decreaseButton.setPreferredSize(new Dimension(image.getWidth(null), image.getHeight(null)));
        }

        return decreaseButton;
    }
    
    protected void installListeners()
    {
        super.installListeners();
        scrollbar.addMouseListener(this);
    }
    
    protected void uninstallListeners()
    {
        super.uninstallListeners();
        scrollbar.removeMouseListener(this);
    }
    
    private Image getThumbImage()
    {
        Image image = null;
        boolean vertical = scrollbar.getOrientation() == VERTICAL;
        
        if(pressed)
        {
            image = UIResourceManager.getImage(vertical? UIResourceManager.KEY_SCROLL_BAR_V_PRESSED_IMAGE:
                UIResourceManager.KEY_SCROLL_BAR_H_PRESSED_IMAGE);
        }
        else if(isThumbRollover())
        {
            image = UIResourceManager.getImage(vertical? UIResourceManager.KEY_SCROLL_BAR_V_ROLLOVER_IMAGE:
                UIResourceManager.KEY_SCROLL_BAR_H_ROLLOVER_IMAGE);
        }
        else
        {
            image = UIResourceManager.getImage(vertical? UIResourceManager.KEY_SCROLL_BAR_V_IMAGE: UIResourceManager.KEY_SCROLL_BAR_H_IMAGE);
        }
        
        return image;
    }

    public Dimension getPreferredSize(JComponent c)
    {
        if(scrollbar.getOrientation() == VERTICAL)
        {
            return new Dimension(DEFAULT_SCROLLBAR_WIDTH, DEFAULT_SCROLLBAR_WIDTH * 3 + 10);
        }
        else
        {
            return new Dimension(DEFAULT_SCROLLBAR_WIDTH * 3 + 10, DEFAULT_SCROLLBAR_WIDTH);
        }
    }

    protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds)
    {
        if(thumbBounds.isEmpty() || !scrollbar.isEnabled())
        {
            return;
        }

        Image image = getThumbImage();
        int width = thumbBounds.width;
        int height = thumbBounds.height;
        int imageWidth = image.getWidth(scrollbar);
        int imageHeight = image.getHeight(scrollbar);
        g.translate(thumbBounds.x, thumbBounds.y);
        
        if(scrollbar.getOrientation() == VERTICAL)
        {
            g.drawImage(image, 0, 0, width, 3, 0, 0, imageWidth, 3, null);
            g.drawImage(image, 0, 3, width, height - 3, 0, 3, imageWidth, imageHeight - 3, null);
            g.drawImage(image, 0, height - 3, width, height, 0, imageHeight - 3, imageWidth, imageHeight, null);
        }
        else
        {
            g.drawImage(image, 0, 0, 3, height, 0, 0, 3, imageHeight, null);
            g.drawImage(image, 3, 0, width - 3, height, 3, 0, imageWidth - 3, imageHeight, null);
            g.drawImage(image, width - 3, 0, width, height, imageWidth - 3, 0, imageWidth, imageHeight, null);
        }
        
        g.translate(-thumbBounds.x, -thumbBounds.y);
    }
    
    protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds)
    {
        if(scrollbar.getOrientation() == VERTICAL)
        {
            g.setColor(BORDER_COLOR);
            g.drawRect(trackBounds.x, trackBounds.y, trackBounds.width - 1, trackBounds.height - 1);
            g.setColor(BACKGROUND);
            g.fillRect(trackBounds.x + 1, trackBounds.y, trackBounds.width - 2, trackBounds.height);
        }
        else
        {
            g.setColor(BORDER_COLOR);
            g.drawRect(trackBounds.x, trackBounds.y, trackBounds.width - 1, trackBounds.height - 1);
            g.setColor(BACKGROUND);
            g.fillRect(trackBounds.x, trackBounds.y + 1, trackBounds.width, trackBounds.height - 2);
        }
    }
    
    public boolean getSupportsAbsolutePositioning()
    {
        return true;
    }
    
    protected void installDefaults()
    {
        minimumThumbSize = new Dimension(DEFAULT_SCROLLBAR_WIDTH, DEFAULT_SCROLLBAR_WIDTH);
        maximumThumbSize = new Dimension(4096, 4096);
        trackHighlight = NO_HIGHLIGHT;

        if(scrollbar.getLayout() == null || (scrollbar.getLayout() instanceof UIResource))
        {
            scrollbar.setLayout(this);
        }
    }
    
    protected void uninstallDefaults()
    {}
    
    public void mousePressed(MouseEvent e)
    {
        boolean flag = SwingUtilities.isRightMouseButton(e)
                        || (!getSupportsAbsolutePositioning() && SwingUtilities.isMiddleMouseButton(e));
        
        if(!flag && getThumbBounds().contains(e.getPoint()))
        {
            boolean oldPress = pressed;
            pressed = true;
            
            if(oldPress != pressed)
            {
                scrollbar.repaint();
            }
        }
    }

    public void mouseReleased(MouseEvent e)
    {
        pressed = false;
    }

    public void mouseClicked(MouseEvent e)
    {}

    public void mouseEntered(MouseEvent e)
    {}

    public void mouseExited(MouseEvent e)
    {}
}